package com.example.zyl.common;

import com.example.zyl.common.enums.CommonCode;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.function.Supplier;

/**
 * <p>
 * 通用返回结果集封装
 * </p>
 *
 * @author zyl
 * @since 2023-11-03
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
public class CommonResult<T> {

    /**
     * code 状态码
     */
    private int code;

    /**
     * msg 返回信息
     */
    private String msg;

    /**
     * 返回true成功, false失败
     */
    private boolean success;

    /**
     * data 数据
     */
    private T data;


    public static <T> CommonResult<T> success() {
        return new CommonResult<T>(CommonCode.SUCCESS.getCode(), CommonCode.SUCCESS.getMsg(), true, null);
    }

    public static <T> CommonResult<T> success(Supplier<T> supplier) {
        return new CommonResult<T>(CommonCode.SUCCESS.getCode(), CommonCode.SUCCESS.getMsg(), true, supplier.get());
    }

    public static <T> CommonResult<T> success(CommonCode commonCode) {
        return new CommonResult<T>(commonCode.getCode(), commonCode.getMsg(), true, null);
    }

    public static <T> CommonResult<T> success(T data) {
        return new CommonResult<T>(CommonCode.SUCCESS.getCode(), CommonCode.SUCCESS.getMsg(), true, data);
    }

    public static <T> CommonResult<T> success(String msg, T data) {
        return new CommonResult<T>(CommonCode.SUCCESS.getCode(), msg, true, data);
    }

    public static <T> CommonResult<T> success(CommonCode commonCode, T data) {
        return new CommonResult<T>(commonCode.getCode(), commonCode.getMsg(), true, data);
    }

    public static <T> CommonResult<T> fail() {
        return new CommonResult<T>(CommonCode.SYSTEM_ERROR.getCode(), CommonCode.SYSTEM_ERROR.getMsg(), false, null);
    }


    public static <T> CommonResult<T> fail(String msg) {
        return new CommonResult<T>(CommonCode.SYSTEM_ERROR.getCode(), msg, false, null);
    }

    public static <T> CommonResult<T> fail(T data) {
        return new CommonResult<T>(CommonCode.SYSTEM_ERROR.getCode(), CommonCode.SYSTEM_ERROR.getMsg(), false, data);
    }

    public static <T> CommonResult<T> fail(CommonCode commonCode) {
        return new CommonResult<T>(commonCode.getCode(), commonCode.getMsg(), false, null);
    }

    public static <T> CommonResult<T> fail(CommonCode commonCode, T data) {
        return new CommonResult<T>(commonCode.getCode(), commonCode.getMsg(), false, data);
    }

    public static <T> CommonResult<T> fail(CommonCode commonCode, boolean bl, T data) {
        return new CommonResult<T>(commonCode.getCode(), commonCode.getMsg(), bl, data);
    }

    public static <T> CommonResult<T> fail(CommonCode commonCode, String msg, boolean bl, T data) {
        return new CommonResult<T>(commonCode.getCode(), msg, bl, data);
    }

    public static <T> CommonResult<T> supplier(Supplier<T> supplier) {
        T t = supplier.get();

        if (t == null) {
            return CommonResult.success(t);
        }

        if (t instanceof Long) {
            if ((Long) t > 0L) {
                return CommonResult.success(t);
            } else {
                return CommonResult.fail(t);
            }
        }
        if (t instanceof Integer) {
            if ((Integer) t > 0) {
                return CommonResult.success(t);
            } else {
                return CommonResult.fail(t);
            }
        }
        if (t instanceof Boolean) {
            if ((Boolean) t) {
                return CommonResult.success(t);
            } else {
                return CommonResult.fail(t);
            }
        }
        return CommonResult.success(t);
    }

    public static <T> Supplier<CommonResult<T>> supplier(T t) {

        if (t == null) {
            return () -> CommonResult.success(t);
        }

        if (t instanceof Long) {
            if ((Long) t > 0L) {
                return () -> CommonResult.success(t);
            } else {
                return () -> CommonResult.fail(t);
            }
        }
        if (t instanceof Integer) {
            if ((Integer) t > 0) {
                return () -> CommonResult.success(t);
            } else {
                return () -> CommonResult.fail(t);
            }
        }
        if (t instanceof Boolean) {
            if ((Boolean) t) {
                return () -> CommonResult.success(t);
            } else {
                return () -> CommonResult.fail(t);
            }
        }
        return () -> CommonResult.success(t);
    }

}
